package com.clougence.cloudcanal.dataprocess.datatransform.common;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * json工具类
 *
 * @author yongSen.wang
 * @date 2021/04/02 16:33
 */
@Slf4j
public class JsonUtil {

    public static ObjectMapper getObjectMapper() {
        return new Jackson2ObjectMapperBuilder().createXmlMapper(false).build()
                //在反序列化时忽略在 json 中存在但 Java 对象不存在的属性
                .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
                //使用List转换jsonArray
                .configure(DeserializationFeature.USE_JAVA_ARRAY_FOR_JSON_ARRAY, true)
                //在序列化时忽略值为 null 的属性
                .setSerializationInclusion(JsonInclude.Include.NON_NULL);

    }

    /**
     * 对象转Json String
     */
    public static String toString(Object obj) {
        try {
            return getObjectMapper().writeValueAsString(obj);
        } catch (Throwable e) {
            log.error("JSON.toJSONString 异常，默认返回空字符串：{}", e.getMessage(), e);
            return StringUtils.EMPTY;
        }
    }

    /**
     * 对象转Json String
     *
     * @param obj 对象
     * @return jsonString
     */
    public static String toJsonString(Object obj) {
        return toString(obj);
    }

    /**
     * 创建jsonObject对象
     *
     * @return ObjectNode
     */
    public static ObjectNode createJsonObjectNode() {
        return getObjectMapper().createObjectNode();
    }

    public static JsonNode readJsonObjectNode(String jsonData) {

        try {
            return getObjectMapper().readTree(jsonData);
        } catch (Exception e) {
            log.error("readJsonObjectNode-->字符串{}转换JsonNode异常，默认返回对象", jsonData, e);
            return null;
        }
    }

    /**
     * JsonNode转java对象
     *
     * @param jsonData 字符串
     * @param beanType 转换对象
     * @return T | null
     */
    public static <T> T jsonToPojo(JsonNode jsonData, Class<T> beanType) {
        try {
            return getObjectMapper().treeToValue(jsonData, beanType);
        } catch (Exception e) {
            log.error("jsonToPojo-->JsonNode{}转换{}异常，默认返回对象", jsonData, beanType.getTypeName(), e);
            return null;
        }
    }

    /**
     * 创建jsonArray对象
     *
     * @return ArrayNode
     */
    public static ArrayNode createJsonArrayNode() {
        return getObjectMapper().createArrayNode();
    }

    /**
     * 字符串转java对象
     *
     * @param jsonData 字符串
     * @param beanType 转换对象
     * @return T | null
     */
    public static <T> T jsonToPojo(String jsonData, Class<T> beanType) {
        try {
            return getObjectMapper().readValue(jsonData, beanType);
        } catch (Exception e) {
            log.error("jsonToPojo-->字符串{}转换{}异常，默认返回对象", jsonData, beanType.getTypeName(), e);
            return null;
        }
    }

    /**
     * 字符串转集合对象
     *
     * @param jsonData json字符串
     * @param beanType 转换集合
     * @return List&lt;T&gt;
     */
    public static <T> List<T> jsonToList(String jsonData, Class<T> beanType) {
        ObjectMapper objectMapper = getObjectMapper();
        JavaType javaType = objectMapper.getTypeFactory().constructParametricType(List.class,
                beanType);
        try {
            return objectMapper.readValue(jsonData, javaType);
        } catch (Exception e) {
            log.error("jsonToList-->字符串{}转换{}异常，默认返回对象", jsonData, beanType.getTypeName(), e);
            return new ArrayList<>();
        }
    }

    /**
     * 根据{@link JavaType}获取Java对象
     *
     * @param jsonData json数据对象
     * @param javaType {@link JavaType}
     * @return <T> T
     */
    public static <T> T jsonToPojo(String jsonData, JavaType javaType) {
        try {
            return getObjectMapper().readValue(jsonData, javaType);
        } catch (Exception e) {
            log.error("jsonToPojo-->字符串{}转换{}异常，默认返回对象", jsonData, javaType.getTypeName(), e);
            return null;
        }
    }

    /**
     * 将Bean转成Map
     *
     * @param obj
     * @return
     * @throws Exception
     */
    public static Map<String, Object> beanToMap(Object obj) throws Exception {
        return getObjectMapper().readValue(toString(obj), new TypeReference<Map<String, Object>>() {
        });

    }

    public static Map<String, String> beanToMapStr(Object obj) throws Exception {
        return getObjectMapper().readValue(toString(obj), new TypeReference<Map<String, String>>() {
        });

    }

}